package uid.elements;

/**
 * @author Patricia Vilain
 */
import java.util.ArrayList;
import java.util.List;

import uid.jsf.Column;
import uid.jsf.CommandLink;
import uid.jsf.Componente;
import uid.jsf.DataTable;
import uid.jsf.OutputLabel;
import uid.jsf.OutputText;
import uid.jsf.PanelGrid;
import uid.jsf.SelectItem;
import uid.jsf.SelectManyCheckbox;

public class OutputStructure extends Structure {

	protected List<Transition> listTransitions;
	private Componente componente;

	public OutputStructure(String name) {
		super(name);
		this.listTransitions = new ArrayList<Transition>();
	}

	/**
	 * Insere o item de dado retornado pelo sistema na estrutura com nome
	 * nameStructure, procurando tambem as estruturas contidas nela.
	 */
	public boolean insertOutputDataItemInStructure(String nameStructure,
			OutputDataItem dataItem) {
		if (this.name.equals(nameStructure)) {
			for (int i = 0; i < this.listDataItems.size(); i++) {
				UIDElement elem = this.listDataItems.get(i);
				if (elem instanceof OutputDataItem
						&& ((OutputDataItem) elem).getName().equals(
								dataItem.getName()))
					return false;
			}
			this.listDataItems.add(dataItem);
			return true;
		} else {
			for (int i = 0; i < this.listStructures.size(); i++) {
				UIDElement elem = this.listStructures.get(i);
				if (elem instanceof OutputStructure) {
					boolean insertionOk = ((OutputStructure) elem)
							.insertOutputDataItemInStructure(nameStructure,
									dataItem);
					if (insertionOk)
						return true;
				}
			}
			return false;
		}
	}

	/**
	 * Remove o item de dado retornado pelo sistema da estrutura com nome
	 * nameStructure, procurando tambem as estruturas contidas nela.
	 */
	public boolean removeOutputDataItemFromStructure(String nameStructure,
			String nameDataItem) {
		if (this.name.equals(nameStructure)) {
			for (int i = 0; i < this.listDataItems.size(); i++) {
				UIDElement elem = this.listDataItems.get(i);
				if (elem instanceof OutputDataItem
						&& ((OutputDataItem) elem).getName().equals(
								nameDataItem)) {
					this.listDataItems.remove(i);
					return true;
				}
			}
			return false;
		} else {
			for (int i = 0; i < this.listStructures.size(); i++) {
				UIDElement elem = this.listStructures.get(i);
				if (elem instanceof OutputStructure) {
					boolean insertionOk = ((OutputStructure) elem)
							.removeOutputDataItemFromStructure(nameStructure,
									nameDataItem);
					if (insertionOk)
						return true;
				}
			}
			return false;
		}
	}

	/**
	 * Insere a estrutura retornada pelo sistema na estrutura com nome
	 * nameStructure, procurando tambem as estruturas contidas nela.
	 */
	public boolean insertOutputStructureInStructure(String nameStructure,
			OutputStructure structure) {
		if (this.name.equals(nameStructure)) {
			for (int i = 0; i < this.listStructures.size(); i++) {
				UIDElement elem = this.listStructures.get(i);
				if (elem instanceof OutputStructure
						&& ((OutputStructure) elem).getName().equals(
								structure.getName()))
					return false;
			}
			this.listStructures.add(structure);
			return true;
		} else {
			for (int i = 0; i < this.listStructures.size(); i++) {
				UIDElement elem = this.listStructures.get(i);
				if (elem instanceof OutputStructure) {
					boolean insertionOk = ((OutputStructure) elem)
							.insertOutputStructureInStructure(nameStructure,
									structure);
					if (insertionOk)
						return true;
				}
			}
			return false;
		}
	}

	/**
	 * Remove a estrutura retornada pelo sistema com nome nameStructure,
	 * procurando tambem as estruturas contidas nela.
	 */
	public boolean removeOutputStructureFromStructure(String nameStructure,
			String nameStructureToBeExcluded) {
		if (this.name.equals(nameStructure)) {
			for (int i = 0; i < this.listStructures.size(); i++) {
				UIDElement elem = this.listStructures.get(i);
				if (elem instanceof OutputStructure
						&& ((OutputDataItem) elem).getName().equals(
								nameStructureToBeExcluded)) {
					this.listStructures.remove(i);
					return true;
				}
			}
			return false;
		} else {
			for (int i = 0; i < this.listStructures.size(); i++) {
				UIDElement elem = this.listStructures.get(i);
				if (elem instanceof OutputStructure) {
					boolean insertionOk = ((OutputStructure) elem)
							.removeOutputStructureFromStructure(nameStructure,
									nameStructureToBeExcluded);
					if (insertionOk)
						return true;
				}
			}
			return false;
		}
	}

	public OutputDataItem getOutputDataItemFromStructure(String nameDataItem,
			String nameStructure) {
		if (this.name.equals(nameStructure)) {
			for (int i = 0; i < this.listDataItems.size(); i++) {
				UIDElement elem = this.listDataItems.get(i);
				if (elem instanceof OutputDataItem
						&& ((OutputDataItem) elem).getName().equals(
								nameDataItem)) {
					return (OutputDataItem) elem;
				}
			}
			return null;
		} else {
			for (int i = 0; i < this.listStructures.size(); i++) {
				UIDElement elem = this.listStructures.get(i);
				if (elem instanceof OutputStructure) {
					OutputDataItem dataItem = ((OutputStructure) elem)
							.getOutputDataItemFromStructure(nameDataItem,
									nameStructure);
					if (dataItem != null)
						return dataItem;
				}
			}
			return null;
		}
	}

	public OutputStructure getOutputStructureFromStructure(
			String nameStructure, String nameExternalStructure) {
		if (this.name.equals(nameExternalStructure)) {
			for (int i = 0; i < this.listStructures.size(); i++) {
				UIDElement elem = this.listStructures.get(i);
				if (elem instanceof OutputStructure
						&& ((OutputStructure) elem).getName().equals(
								nameStructure)) {
					return (OutputStructure) elem;
				}
			}
			return null;
		} else {
			for (int i = 0; i < this.listStructures.size(); i++) {
				UIDElement elem = this.listStructures.get(i);
				if (elem instanceof OutputStructure) {
					OutputStructure structure = ((OutputStructure) elem)
							.getOutputStructureFromStructure(nameStructure,
									nameExternalStructure);
					if (structure != null)
						return structure;
				}
			}
			return null;
		}
	}

	public List<Transition> getTransitions() {
		return this.listTransitions;
	}

	public void insertTransition(Transition transition) {
		for (int i = 0; i < this.listTransitions.size(); i++) {
			Transition trans = this.listTransitions.get(i);
			if (trans.getId().equals(transition.getId()))
				throw new UIDException(UIDException.EXISTING_TRANSITION,
						"There is already a transition with this id");
		}
		this.listTransitions.add(transition);
	}
}
